package com.jacen.etl.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author richfans
 *
 *	Hibernate 工具类  
 *
 */
public class NHibernateUtil {
	
    private static Logger log = LoggerFactory.getLogger(NHibernateUtil.class);
    public static final SessionFactory sessionFactory;
    static {
        try {
        	Configuration cfg = new Configuration();
    		cfg.configure("/hibernate.cfg.xml");		
    		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();		
    		sessionFactory = cfg.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
        	ex.printStackTrace();
            log.error("Initial SessionFactory creation failed.", ex);
            throw new ExceptionInInitializerError(ex);
        } // end of the try - catch block
    } // end of static block

    public static final ThreadLocal<Session> localSession = new ThreadLocal<Session>();
    public static final ThreadLocal<Transaction> localTransaction = new ThreadLocal<Transaction>();
    
    public static Session openSession() throws HibernateException {
    	Session session = (Session)localSession.get();
    	if(session == null){
    		session = sessionFactory.openSession();
    		localSession.set(session);
    	}
    	
    	if(!session.isOpen()){
    		localSession.set(null);
    		session = sessionFactory.openSession();
    		localSession.set(session);
    	}
        return session;
    }
    
    public static void closeSession() throws HibernateException {
    	Session session = (Session)localSession.get();
    	localSession.set(null);
    	if(session != null){
	        session.close();
	        session = null;
    	}
    }
    
    public static Transaction beginTransaction() throws HibernateException {
    	Transaction tx = (Transaction)localTransaction.get();
    	if(tx == null){
    		tx = openSession().beginTransaction();
    		localTransaction.set(tx);
    	}
    	if(tx.wasCommitted()) {
    		tx = null;
    		tx = openSession().beginTransaction();
    		localTransaction.set(tx);
    	}
    	return tx;
    }

    public static void commitTransaction() throws HibernateException {
    	Transaction tx = (Transaction)localTransaction.get();
    	localTransaction.set(null);
    	if(tx != null){
    		tx.commit();
    		tx = null;
    	}
    }
    
    public static void rollbackTransaction() throws HibernateException {
    	Transaction tx = (Transaction)localTransaction.get();
    	localTransaction.set(null);
    	if(tx != null){
    		tx.rollback();
    		tx = null;
    	}
    }

}